package core

import (
	"strings"
	"fmt"
	"global/constants"
	"github.com/garyburd/redigo/redis"
	"global/libs/structs"
	"encoding/json"
)

// 获取Cmc的URl
func GetCmcUrl(debug bool, uri string) string {
	var url string
	if debug {
		url = constants.CmcSandboxBaseUrl
	} else {
		url = constants.CmcProductionBaseUrl
	}

	url = strings.TrimRight(url, "/")
	uri = strings.TrimLeft(uri, "/")

	return fmt.Sprintf("%s/%s", url, uri)
}

// 获取市场
func GetMarketQuotesInfo(conn redis.Conn, symbol string) (map[string]structs.Quote, error) {
	quotesTypes := []string{"USD", "CNY", "BTC"}
	value := make(map[string]structs.Quote)
	for _, qt := range quotesTypes {
		key := fmt.Sprintf(constants.CmcCoinQuoteInfoKey, symbol, qt)
		v, err := redis.Values(conn.Do("HGETALL", key))
		if err != nil {
			return nil, err
		}
		var val structs.Quote
		if err := redis.ScanStruct(v, &val); err != nil {
			return nil, err
		}
		value[qt] = val
	}
	return value, nil
}

// 批量获取交易信息
func GetCoinInfoFromCmcMulti(conn redis.Conn, coins []string) ([]*structs.MarketCoinBase, error) {
	conn.Send("MULTI")
	for _, v := range coins {
		key := fmt.Sprintf(constants.CmcCoinMarketInfoKey, v)
		conn.Send("HGETALL", key)
	}
	values, err := redis.Values(conn.Do("EXEC"))
	if err != nil {
		return nil, err
	}

	marketCoins := make([]*structs.MarketCoinBase, 0)
	for _, v := range values {
		var coin structs.MarketCoinBase
		val, _ := redis.Values(v, nil)
		err := redis.ScanStruct(val, &coin)
		if err != nil {
			return nil, err
		}
		marketCoins = append(marketCoins, &coin)
	}
	return marketCoins, nil
}

// 获取币种消息
func GetCoinMarketInfo(conn redis.Conn, coinSlug string) (*structs.MarketCoinBase, error) {
	key := fmt.Sprintf(constants.CmcCoinMarketInfoKey, coinSlug)
	v, err := redis.Values(conn.Do("HGETALL", key))
	if err != nil {
		return nil ,err
	}
	var val structs.MarketCoinBase
	if err := redis.ScanStruct(v, &val); err != nil {
		return nil, err
	}
	return &val, nil
}

func SaveExchangePairVolume24h(conn redis.Conn, slug string, pairs *structs.CmcExchangeMarketPairs) error {
	conn.Send("MULTI")
	for _, v := range pairs.MarketPairs {
		symbol := strings.ToLower(strings.Replace(v.MarketPair, "/", "_", -1))
		for k, item := range v.Quote {
			key := fmt.Sprintf(constants.CmcExchangePairVolume24hKey, slug, symbol, k)
			conn.Send("HMSET", redis.Args{}.Add(key).AddFlat(&item)...)
		}
	}
	_, err := conn.Do("EXEC")
	return err
}

// 保存交易所交易对
func SaveExchangePairs(conn redis.Conn, slug string, symbols []structs.Symbol) error {
	key := fmt.Sprintf(constants.CmcExchangePairKey, slug)
	s := make(map[string]string)
	for _, symbol := range symbols {
		key := symbol.From + "_" + symbol.To
		tmp, err := json.Marshal(symbol)
		if err != nil {
			return err
		}
		s[key] = string(tmp)
	}
	conn.Send("MULTI")
	for symbol, item := range s {
		conn.Send("HSET", key, symbol, item)
	}
	_, err := conn.Do("EXEC")
	return err
}

// 保存币种当前市场行情
func SaveCoinMarketInfo(conn redis.Conn, coins []structs.MarketQuote) error {
	conn.Send("MULTI")
	for _, coin := range coins {
		symbol := strings.ToLower(coin.Symbol)
		key := fmt.Sprintf(constants.CmcCoinMarketInfoKey, symbol)

		for s, q := range coin.Quotes {
			k := fmt.Sprintf(constants.CmcCoinQuoteInfoKey, symbol, s)
			conn.Do("HMSET", redis.Args{}.Add(k).AddFlat(&q)...)
		}

		coin.Quotes = nil
		conn.Send("HMSET", redis.Args{}.Add(key).AddFlat(&coin)...)
	}
	_, err := conn.Do("EXEC")
	return err
}

// 保存交易所所有币种24h交易量行情
func SaveExchangeVolume24h(conn redis.Conn, vols []structs.ExchangeLatestData) error {
	conn.Send("MULTI")
	for _, vol := range vols {
		for s, v := range vol.Quotes {
			key := fmt.Sprintf(constants.CmcExchangeVolume24hKey, vol.Slug, s)
			conn.Send("HMSET", redis.Args{}.Add(key).AddFlat(&v)...)
		}
	}
	_, err := conn.Do("EXEC")
	return err
}